import localforage from 'localforage';
import { 
  User, 
  UserPreferences, 
  ColorScheme, 
  ColorUsageStats, 
  UserDataExport 
} from '@/types';
import { generateId } from '@/utils';

/**
 * 本地存储服务类
 * 使用 localforage 实现数据持久化存储
 */
class StorageServiceClass {
  private static instance: StorageServiceClass;
  private storage: LocalForage;

  private constructor() {
    // 配置 localforage
    this.storage = localforage.createInstance({
      name: 'ColorPaletteApp',
      version: 1.0,
      storeName: 'colordata',
      description: '色彩搭配应用数据存储'
    });
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): StorageServiceClass {
    if (!StorageServiceClass.instance) {
      StorageServiceClass.instance = new StorageServiceClass();
    }
    return StorageServiceClass.instance;
  }

  /**
   * 获取用户信息
   */
  async getUser(): Promise<User | null> {
    try {
      return await this.storage.getItem<User>('user');
    } catch (error) {
      console.error('Failed to get user:', error);
      return null;
    }
  }

  /**
   * 保存用户信息
   */
  async saveUser(user: User): Promise<void> {
    try {
      await this.storage.setItem('user', user);
    } catch (error) {
      console.error('Failed to save user:', error);
      throw new Error('保存用户信息失败');
    }
  }

  /**
   * 获取用户偏好设置
   */
  async getPreferences(): Promise<UserPreferences> {
    try {
      const preferences = await this.storage.getItem<UserPreferences>('preferences');
      return preferences || this.getDefaultPreferences();
    } catch (error) {
      console.error('Failed to get preferences:', error);
      return this.getDefaultPreferences();
    }
  }

  /**
   * 保存用户偏好设置
   */
  async savePreferences(preferences: UserPreferences): Promise<void> {
    try {
      await this.storage.setItem('preferences', preferences);
    } catch (error) {
      console.error('Failed to save preferences:', error);
      throw new Error('保存偏好设置失败');
    }
  }

  /**
   * 获取所有色彩方案
   */
  async getColorSchemes(): Promise<ColorScheme[]> {
    try {
      const schemes = await this.storage.getItem<ColorScheme[]>('colorSchemes');
      return schemes || [];
    } catch (error) {
      console.error('Failed to get color schemes:', error);
      return [];
    }
  }

  /**
   * 保存色彩方案
   */
  async saveColorScheme(scheme: ColorScheme): Promise<void> {
    try {
      const schemes = await this.getColorSchemes();
      const existingIndex = schemes.findIndex(s => s.id === scheme.id);
      
      if (existingIndex >= 0) {
        // 更新现有方案
        schemes[existingIndex] = { ...scheme, updatedAt: new Date() };
      } else {
        // 添加新方案
        schemes.push({ ...scheme, id: scheme.id || generateId() });
      }
      
      await this.storage.setItem('colorSchemes', schemes);
      
      // 更新统计数据
      await this.updateStats();
    } catch (error) {
      console.error('Failed to save color scheme:', error);
      throw new Error('保存色彩方案失败');
    }
  }

  /**
   * 删除色彩方案
   */
  async deleteColorScheme(id: string): Promise<void> {
    try {
      const schemes = await this.getColorSchemes();
      const filteredSchemes = schemes.filter(s => s.id !== id);
      
      await this.storage.setItem('colorSchemes', filteredSchemes);
      await this.updateStats();
    } catch (error) {
      console.error('Failed to delete color scheme:', error);
      throw new Error('删除色彩方案失败');
    }
  }

  /**
   * 获取收藏的色彩方案
   */
  async getFavoriteSchemes(): Promise<ColorScheme[]> {
    try {
      const schemes = await this.getColorSchemes();
      return schemes.filter(s => s.isFavorite);
    } catch (error) {
      console.error('Failed to get favorite schemes:', error);
      return [];
    }
  }

  /**
   * 切换色彩方案收藏状态
   */
  async toggleFavorite(id: string): Promise<void> {
    try {
      const schemes = await this.getColorSchemes();
      const scheme = schemes.find(s => s.id === id);
      
      if (scheme) {
        scheme.isFavorite = !scheme.isFavorite;
        scheme.updatedAt = new Date();
        await this.storage.setItem('colorSchemes', schemes);
      }
    } catch (error) {
      console.error('Failed to toggle favorite:', error);
      throw new Error('更新收藏状态失败');
    }
  }

  /**
   * 获取统计数据
   */
  async getStats(): Promise<ColorUsageStats> {
    try {
      const stats = await this.storage.getItem<ColorUsageStats>('stats');
      return stats || this.getDefaultStats();
    } catch (error) {
      console.error('Failed to get stats:', error);
      return this.getDefaultStats();
    }
  }

  /**
   * 更新统计数据
   */
  async updateStats(): Promise<void> {
    try {
      const schemes = await this.getColorSchemes();
      const stats = this.calculateStats(schemes);
      await this.storage.setItem('stats', stats);
    } catch (error) {
      console.error('Failed to update stats:', error);
    }
  }

  /**
   * 搜索色彩方案
   */
  async searchSchemes(query: string, tags?: string[]): Promise<ColorScheme[]> {
    try {
      const schemes = await this.getColorSchemes();
      const lowercaseQuery = query.toLowerCase();
      
      return schemes.filter(scheme => {
        const matchesQuery = !query || 
          scheme.name.toLowerCase().includes(lowercaseQuery) ||
          scheme.description?.toLowerCase().includes(lowercaseQuery);
        
        const matchesTags = !tags || tags.length === 0 ||
          tags.some(tag => scheme.tags.includes(tag));
        
        return matchesQuery && matchesTags;
      });
    } catch (error) {
      console.error('Failed to search schemes:', error);
      return [];
    }
  }

  /**
   * 导出用户数据
   */
  async exportData(): Promise<UserDataExport> {
    try {
      const [user, schemes, preferences, stats] = await Promise.all([
        this.getUser(),
        this.getColorSchemes(),
        this.getPreferences(),
        this.getStats()
      ]);

      return {
        user,
        schemes,
        preferences,
        stats,
        exportDate: new Date(),
        version: '1.0.0'
      };
    } catch (error) {
      console.error('Failed to export data:', error);
      throw new Error('导出数据失败');
    }
  }

  /**
   * 导入用户数据
   */
  async importData(data: UserDataExport): Promise<void> {
    try {
      // 验证数据格式
      if (!data.version || !data.exportDate) {
        throw new Error('无效的数据格式');
      }

      // 导入数据
      const promises: Promise<void>[] = [];
      
      if (data.user) {
        promises.push(this.saveUser(data.user));
      }
      
      if (data.preferences) {
        promises.push(this.savePreferences(data.preferences));
      }
      
      if (data.schemes && data.schemes.length > 0) {
        promises.push(this.storage.setItem('colorSchemes', data.schemes));
      }
      
      if (data.stats) {
        promises.push(this.storage.setItem('stats', data.stats));
      }

      await Promise.all(promises);
    } catch (error) {
      console.error('Failed to import data:', error);
      throw new Error('导入数据失败');
    }
  }

  /**
   * 清空所有数据
   */
  async clearAll(): Promise<void> {
    try {
      await this.storage.clear();
    } catch (error) {
      console.error('Failed to clear data:', error);
      throw new Error('清空数据失败');
    }
  }

  /**
   * 获取存储空间使用情况
   */
  async getStorageInfo(): Promise<{
    used: number;
    available: number;
    itemCount: number;
  }> {
    try {
      const keys = await this.storage.keys();
      let totalSize = 0;
      
      for (const key of keys) {
        const item = await this.storage.getItem(key);
        totalSize += JSON.stringify(item).length;
      }
      
      return {
        used: totalSize,
        available: 10 * 1024 * 1024 - totalSize, // 假设10MB限制
        itemCount: keys.length
      };
    } catch (error) {
      console.error('Failed to get storage info:', error);
      return { used: 0, available: 0, itemCount: 0 };
    }
  }

  /**
   * 备份数据到文件
   */
  async backupToFile(): Promise<string> {
    try {
      const data = await this.exportData();
      return JSON.stringify(data, null, 2);
    } catch (error) {
      console.error('Failed to backup data:', error);
      throw new Error('备份数据失败');
    }
  }

  /**
   * 从文件恢复数据
   */
  async restoreFromFile(jsonData: string): Promise<void> {
    try {
      const data = JSON.parse(jsonData) as UserDataExport;
      await this.importData(data);
    } catch (error) {
      console.error('Failed to restore data:', error);
      throw new Error('恢复数据失败');
    }
  }

  // 私有方法

  /**
   * 获取默认偏好设置
   */
  private getDefaultPreferences(): UserPreferences {
    return {
      defaultColorMode: 'hex',
      theme: 'auto',
      language: 'zh-CN',
      autoSave: true,
      maxHistoryItems: 100,
      showColorNames: true,
      enableAnimations: true
    };
  }

  /**
   * 获取默认统计数据
   */
  private getDefaultStats(): ColorUsageStats {
    return {
      totalSchemes: 0,
      favoriteColors: [],
      colorDistribution: {},
      averageColorsPerScheme: 0,
      creationFrequency: {},
      mostUsedTypes: {}
    };
  }

  /**
   * 计算统计数据
   */
  private calculateStats(schemes: ColorScheme[]): ColorUsageStats {
    const colorDistribution: { [hueRange: string]: number } = {};
    const creationFrequency: { [date: string]: number } = {};
    const mostUsedTypes: { [type: string]: number } = {};
    const allColors = schemes.flatMap(s => s.colors);

    // 计算色相分布
    allColors.forEach(color => {
      const hue = color.hsl.h;
      const range = this.getHueRange(hue);
      colorDistribution[range] = (colorDistribution[range] || 0) + 1;
    });

    // 计算创建频率
    schemes.forEach(scheme => {
      const date = scheme.createdAt.toDateString();
      creationFrequency[date] = (creationFrequency[date] || 0) + 1;
    });

    // 计算最常用类型
    schemes.forEach(scheme => {
      mostUsedTypes[scheme.type] = (mostUsedTypes[scheme.type] || 0) + 1;
    });

    // 获取最受欢迎的颜色
    const colorFrequency = new Map<string, { color: any; count: number }>();
    allColors.forEach(color => {
      const hex = color.hex;
      if (colorFrequency.has(hex)) {
        colorFrequency.get(hex)!.count++;
      } else {
        colorFrequency.set(hex, { color, count: 1 });
      }
    });

    const favoriteColors = Array.from(colorFrequency.values())
      .sort((a, b) => b.count - a.count)
      .slice(0, 10)
      .map(item => item.color);

    return {
      totalSchemes: schemes.length,
      favoriteColors,
      colorDistribution,
      averageColorsPerScheme: schemes.length > 0 ? allColors.length / schemes.length : 0,
      creationFrequency,
      mostUsedTypes
    };
  }

  /**
   * 根据色相值获取色相范围名称
   */
  private getHueRange(hue: number): string {
    if (hue >= 0 && hue < 30) return '红色';
    if (hue >= 30 && hue < 60) return '橙色';
    if (hue >= 60 && hue < 90) return '黄色';
    if (hue >= 90 && hue < 150) return '绿色';
    if (hue >= 150 && hue < 210) return '青色';
    if (hue >= 210 && hue < 270) return '蓝色';
    if (hue >= 270 && hue < 330) return '紫色';
    return '洋红';
  }
}

// 导出单例实例
export const StorageService = StorageServiceClass.getInstance();